using Game;

namespace SCIENEW {
    /// <summary>
    /// 对于此类，机器ID中前三位为机器特殊值（可以是朝向（6向）等等），后15位为不同机器的序号
    /// 为保证兼容性，每个机器都有8个特殊值形式
    /// </summary>
    public static class DevicesBlockManager {
        /// <summary>
        /// 所有设备的集合，设备数字ID的前15位为它在这个集合里的索引
        /// </summary>
        public static DeviceBlock[] Devices = Array.Empty<DeviceBlock>();

        /// <summary>
        /// 机器字符串标识符和对应的数字ID的对应表，int[]标识不同朝向的此机器
        /// </summary>
        public static Dictionary<string, int[]> IdMap;

        public static void Init() {
            Devices = [
                new PresserDevice(),
                new KibblerDevice(),
                new RiflingDevice(),
                new SqueezerDevice(),
                new MachineToolDevice(),
                new IronFurnaceDevice(),
                new LiquidPumpDevice(),
                new FluidTankDevice(),
                new SteamEngineDevice(),
                new StirlingEngineDevice(),
                new IronChestDevice(),
                new DrillerDevice(),
				new CrusherDevice(),
                new DiversionDevice(),
				new SteelChestDevice(),
                new SpinnerDevice(),
                new CupronickelPipeDevice(),
                new SifterDevice(),
                new CheckValveDevice(),
				new UnloaderDevice(),
                new InserterDevice(),
                new FireBoxDevice(),
                new AirBlowerDevice(),
                new BlastFurnaceDevice(),
                new BlastFurnacePortDevice(),
                new BlastCastingBasinDevice(),
                new SorterDevice(),
                new CokeOvenDevice(),
                new TransferDevice(),
                new CokeOvenPortDevice(),
                new CastingTroughDevice(),
                new HearthFurnaceInputPortDevice(),
                new HearthFurnaceOutputPortDevice(),
                new OpenHearthFurnaceDevice(),
                new HearthFurnaceCastingBasinDevice(),
                new SteamTurbineDevice(),
                new GeneratorDevice(),
                new MagnetizerDevice(),
                new SeparatorDevice(),
                new ElectricFurnaceDevice(),
                new ReactorDevice(),
#if false
                new CastDevice(),
                new DrillerDevice(),
                new CrusherDevice(),
                new EngineDevice("蒸汽轮机", "SteamTurbineDevice", "蒸汽轮机", 143, 175),
                new EngineDevice("燃气轮机", "GasTurbineDevice", "燃气轮机", 171, 187),
                new EngineDevice("内燃机", "InternalCombustionEngineDevice", "内燃机是一种高效发动机，它通过燃料在气缸内的燃烧膨胀进行做功，进而输出能量。", 124, 124),
                new EngineDevice("柴油发动机", "DieselEngineDevice", "柴油发动机", 124, 124),
                new EngineDevice("核冲程发动机", "NuclearPulseEngine", "一种利用核能加热气体做功的发动机，做功时会输出核污染。", 152, 153, 141, 141) {
                    VerticalSlot = 137
                },
#endif
            ];

            //添加字符串标识符和ID的对于关系
            IdMap = new Dictionary<string, int[]>();
            for (int i = 0; i < Devices.Length; i++) {
                //创建完整值
                int baseData = i << 3;//不包含3位特殊值的机器id
                int[] data = new int[8];
                for (int j = 0; j < 8; j++) {
                    data[j] = Terrain.MakeBlockValue(BaseDeviceBlock.Index, 0, baseData | (j & 0b111));
                }
                IdMap.Add(Devices[i].GetCraftingId(), data);
            }
        }

        public static void LateInit() {
            for (int i = 0; i < Devices.Length; i++) {
                //创建合成谱
                CraftingRecipesManager.m_recipes.AddRange(Devices[i].GenerateProceduralRecipe(IdMap.Values.ElementAt(i)[0]));
            }
        }

        public static DeviceBlock GetDevice(int value) {
            int data = Terrain.ExtractData(value) >> 3;//撇去前三位特殊值位
            return data < Devices.Length ? Devices[data] : Devices[0];
        }

        public static DeviceBlock GetDevice(string id) => GetDevice(IdMap[id][0]);

        public static T? GetDevice<T>() where T : DeviceBlock {
            foreach (var device in Devices) {
                if (device.GetType() == typeof(T)) return device as T;
            }
            return null;
        }

        /// <summary>
        /// 通过机器的字符串ID标识符和机器特殊值寻找机器的方块完整值
        /// </summary>
        /// <param name="id"></param>
        /// <param name="innerData"></param>
        /// <returns></returns>
        public static int GetDeviceValue(string id, int innerData) => IdMap[id][innerData];

        public static string GetDeviceCraftingID(int value) => GetDevice(value).GetCraftingId();

        public static int GetDeviceValueByType(Type deviceType, int innerData = 0) {
            if (!deviceType.IsSubclassOf(typeof(DeviceBlock))) return 0;
            DeviceBlock deviceBlock = Devices.First(x => x.GetType() == deviceType);
            return GetDeviceValue(deviceBlock.GetCraftingId(), innerData);
        }
    }
}